// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import '../camera.dart';

/// A widget showing a live camera preview.
class CameraPreview extends StatelessWidget {
  /// Creates a preview widget for the given camera controller.
  const CameraPreview(this.controller, {super.key, this.child, this.focusKey});

  /// The controller for the camera that the preview is shown for.
  final CameraController controller;

  /// A widget to overlay on top of the camera preview
  final Widget? child;

  final Key? focusKey;

  @override
  Widget build(BuildContext context) {
    if(controller.value.isInitialized == false) {
       return Container();
    }
    return ValueListenableBuilder<CameraValue>(
      valueListenable: controller,
      builder: (BuildContext context, Object? value, Widget? child) {
        // print("focus $focusX -- $focusY");
        return AspectRatio(
          aspectRatio: _isLandscape()
              ? controller.value.aspectRatio
              : (1 / controller.value.aspectRatio),
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              _wrapInRotatedBox(child: controller.buildPreview()),
              child ?? Container(),
              if(focusKey != null) FocusView(key: focusKey),
            ],
          ),
        );
      },
      child: child,
    );
  }

  Widget _wrapInRotatedBox({required Widget child}) {
    if (kIsWeb || defaultTargetPlatform != TargetPlatform.android) {
      return child;
    }

    return RotatedBox(
      quarterTurns: _getQuarterTurns(),
      child: child,
    );
  }

  bool _isLandscape() {
    return <DeviceOrientation>[
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.landscapeRight
    ].contains(_getApplicableOrientation());
  }

  int _getQuarterTurns() {
    final Map<DeviceOrientation, int> turns = <DeviceOrientation, int>{
      DeviceOrientation.portraitUp: 0,
      DeviceOrientation.landscapeRight: 1,
      DeviceOrientation.portraitDown: 2,
      DeviceOrientation.landscapeLeft: 3,
    };
    return turns[_getApplicableOrientation()]!;
  }

  DeviceOrientation _getApplicableOrientation() {
    return controller.value.isRecordingVideo
        ? controller.value.recordingOrientation!
        : (controller.value.previewPauseOrientation ??
            controller.value.lockedCaptureOrientation ??
            controller.value.deviceOrientation);
  }
}

//焦点框
class FocusView extends StatefulWidget {
  const FocusView({Key? key}) : super(key: key);

  @override
  State<FocusView> createState() => FocusViewState();
}

class FocusViewState extends State<FocusView> with TickerProviderStateMixin {

  double? _focusX;
  double? _focusY;

  late Animation<double> _scaleAnimation;
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 300),
    );

    _scaleAnimation = Tween<double>(begin: 2.0, end: 1.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Curves.easeOut,
      ),
    );
    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        Future.delayed(Duration(milliseconds: 300), () {
          setState(() {
            _focusX = null;
            _focusY = null;
          });
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_focusX == null || _focusY == null) {
      return SizedBox();
    }
    return Positioned(
        left: _focusX! - 40,
        top: _focusY! - 40,
        child: ScaleTransition(child: Container(
          width: 80,
          height: 80,
          decoration: BoxDecoration(
              border: Border.all(color: Colors.white, width: 1.5),
              borderRadius: BorderRadius.circular(8)),
        ), scale: _scaleAnimation));
  }

  void handleTapDown(double x, double y) {
    setState(() {
      _focusX = x;
      _focusY = y;
    });
    if (_controller.isAnimating) {
      _controller.stop();
    }
    _controller.forward(from: 0.0); // Only start if not already animating
  }
}
